#pragma once

#include "rulebase2b.h"

/**
 * This class makes a specific use of LongInstance objects. Instead of keeping the coordinates where the 
 * rule applies, it keeps the coordinates where the rule does NOT apply. This class also only keeps the 
 * rules (i.e. long instances) where the output is Black. If an IF part cannot be found in the object,
 * it will be considered to be a White pixel.
 */
class RuleBaseption2B
{
private:
	vector<LongInstance2B> rules;
	/** Returns true if the given coordinate is an element of rule::coordinate. Here they are threated as exceptions for the rule.*/
	bool cooIsException (const LongInstance2B& rule, const Coordinate& coo) const;

public:
	RuleBaseption2B();
	RuleBaseption2B (const RuleBaseption2B& other);
	RuleBaseption2B (const RuleBase2B& rb);
	RuleBaseption2B& operator= (const RuleBaseption2B& other);
	/** Creates the next layer Image in the eim according to the history of previous layers and the rules in this object. */
	void advanceEIM (EightLayerIM& eim) const;

	int getFeatureSize() const;
	/**
	 * Returnes the net information size (in bits) stored in an object.
	 * The returned value is the minimum number of bits that efficiently can give us all the information
	 * in an object.
	 */
	int getNetInfoSizeInBits(void) const;

	double getAverageExceptionsPerRule(void) const;

	int getRulesNum () const;

	friend ostream& operator<< (ostream& stream, const RuleBaseption2B& rbs) 
	{
		stream << "RuleBaseption2B object:\n";
		for (int i = 0; i < (int)rbs.rules.size(); ++i)
			stream << rbs.rules[i];
		stream << endl << "Number of rules: "   << rbs.getRulesNum();
		stream << endl << "RuleBase Size: "     << rbs.getFeatureSize();
		stream << endl << "Info Size in bits: " << rbs.getNetInfoSizeInBits();
		stream << endl << "Average Exceptions Per Rule: " << rbs.getAverageExceptionsPerRule();
		return stream;
	}
};